package config;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class DbTemplate  {

	public DbTemplate() {
		// TODO Auto-generated constructor stub
	}
	
	 public static QueryRunner mfr = new QueryRunner();
	 private static final Log LOG = LogFactory.getLog(DbTemplate.class);
	 
	 public static int insert(String sql, Object[] params) {  
	        int affectedRows = 0;  
	        try {  
	            if (params == null) {  
	                affectedRows = mfr.update(DbManager.getConnection(), sql, params);  
	            } else {  
	                affectedRows = mfr.update(DbManager.getConnection(),sql, params);  
	            }  
	        } catch (SQLException e) {  
	            e.printStackTrace();  
	            LOG.error("insert.插入记录错误：" + sql, e);  
	        }finally{
	        	 DbManager.closeConnection();
	        } 
	       
	        return affectedRows;  
	    }  
	 /** 
	     * 插入数据库，返回自动增长的主键 
	     *  
	     * @param sql - 
	     *            执行的sql语句 
	     * @return 主键  
	     */  
	    public static int insertForKey(String sql, Object[] params) {  
	        int key = 0;  
	        int affectedRows = 0;  
	        try {  
	            if (params == null) {  
	                affectedRows = mfr.update(DbManager.getConnection(),sql);  
	            } else {  
	                affectedRows = mfr.update(DbManager.getConnection(),sql, params);  
	            }  
	           key = Integer.valueOf(mfr.query(DbManager.getConnection(),"SELECT LAST_INSERT_ID()", new ScalarHandler(1)).toString());
	        } catch (SQLException e) {  
	            e.printStackTrace();  
	            LOG.error("insertForKey.插入记录错误：" + sql, e);  
	        } finally{
	        	 DbManager.closeConnection();
	        } 
	        return key;  
	    }  
	 
	    /** 
	      * 获得第一个查询第一行第一列 
	      * @param sql 
	      * @param params 
	      * @return 
	      */  
	    
	    public static<T> T getAnAttr(String sql, Object[] params ,Class<T> clazz){  
	  
	    	T c = null;
	        try {  
	            c=  (T)mfr.query(DbManager.getConnection(),sql,new BeanHandler(clazz),params);  
	        } catch (SQLException e) {  
	            e.printStackTrace();  
	            LOG.error("getAnAttr.查询对象记录错误：" + sql, e);  
	        }finally{
	        	 DbManager.closeConnection();
	        }   
	        return c;
	    }
	    /** 
	     * 查询返回单个对象 
	     * @param sql 
	     * @param clazz 
	     * @return 
	     */   
	    public static<T> T queryForObject(String sql,Object param[],Class<T> clazz){        
	        T obj = null;  
	        try {             
	            obj = (T)mfr.query(DbManager.getConnection(),sql,new BeanHandler(clazz), param);            
	        } catch (SQLException e) {            
	            e.printStackTrace();  
	            LOG.error("queryForObject.查询对象记录错误：" + sql, e); 
	        }finally{
	        	 DbManager.closeConnection();
	        }    
	        return obj;  
	    }  
	    
	    /**
	     * 查询最大值用
	     * */
	    public static<T> T queryObject(String sql,Class<T> clazz){        
	        T obj = null;  
	        try {             
	        	
	            obj = (T)mfr.query(DbManager.getConnection(),sql,new BeanHandler(clazz));            
	        } catch (SQLException e) {            
	            e.printStackTrace();  
	            LOG.error("queryForObject.查询对象记录错误：" + sql, e); 
	        } finally{
	        	 DbManager.closeConnection();
	        }   
	        return obj;  
	    }  
	    
	    /** 
	     * 查询返回list对象 
	     * @param sql 
	     * @param clazz 
	     * @return 
	     */  
	    public static<T> List<T> queryForList(String sql,Object[] param,Class<T> clazz){  
	    	List<T> obj = null;
	        try {  
	            obj = (List<T>)mfr.query(DbManager.getConnection(),sql,new BeanListHandler(clazz),param);             
	        } catch (SQLException e) {            
	            e.printStackTrace();  
	            LOG.error("queryForOList.查询对象记录错误：" + sql, e); 
	        }finally{
	        	 DbManager.closeConnection();
	        }    
	       
	        return obj;  
	    }  
	    
	    /** 
	     * 无参数查询返回list对象 
	     * @param sql 
	     * @param clazz 
	     * @return 
	     */  
	    public static<T> List<T> queryForListNoParam(String sql,Class<T> clazz){  
	        List<T> obj = null;  
	        try {  
	            obj = (List<T>)mfr.query(DbManager.getConnection(),sql,new BeanListHandler(clazz));  
	        } catch (SQLException e) {            
	            e.printStackTrace();  
	            LOG.error("queryForOList.查询对象记录错误：" + sql, e); 
	        }finally{
	        	 DbManager.closeConnection();
	        } 
	        return obj;  
	    }  
	    /** 
	     * 更新 操作
	     * @param sql 
	     * @return 
	     */  
	      
	    public static int update(String sql,Object[] param){  
	        int i=0;  
	        try {  
	            i = mfr.update(DbManager.getConnection(),sql,param);  
	        }catch(SQLException e) {  
	            e.printStackTrace();  
	            LOG.error("update.查询对象记录错误：" + sql, e); 
	        }finally{
	        	 DbManager.closeConnection();
	        }  
	        return i;  
	  
	    }  
	    /** 
	     * 更新 操作
	     * @param sql 
	     * @return 
	     */  
	      
	    public static int update(Connection conn,String sql,Object[] param){  
	        int i=0;  
	        try {  
	            i = mfr.update(conn,sql,param);  
	        }catch(SQLException e) {  
	            e.printStackTrace();  
	            LOG.error("update.查询对象记录错误：" + sql, e); 
	        }
	        return i;  
	  
	    }  	
	    	    
	    
	    /**
	     * 批量执行指定的SQL语句
	     * 逐条执行，批量更新操作用（新增也可，但效率没有batchInsert高）
	     * @param sql
	     * @param params
	     * @return
	     * 
	     */
	    public static int[] batch(String sql, Object[][] params) {
	    	int[] r =new int[params.length];
	        try{
	            r =  mfr.batch(DbManager.getConnection(),sql, params);
	        }catch(SQLException e){
	        	 e.printStackTrace();  
	        	  LOG.error("batch.批量操作记录错误：" + sql, e); 
	        }finally{
	        	 DbManager.closeConnection();
	        } 
	        return r;
	        
	    }
	     /* 批量插入SQL语句
	     * @param sql
	     * @param params
	     * @return
	     * 1、将sql字符串进行截取获取values 以后的内容，
	     * 	例如： insert into table values(?,?);
	     * 先获得(?,?)
	     * 2、获取二位数组长度，并创建一个包含二维数组所有数据的一个一维数组，如参数为params[6][5],则创建一个长度为6*5  30长度的数组
	     * 3、组合sql字符串，形成insert into table values(?,?)，(?,?)，(?,?) 形式 
	     * 4、组合参数，将二维数组变成一维数组，最后执行插入操作
	     * 
	     */
	    public static int batchInsert(String sql, Object[][] params) {
	    	int r =0;
	    	//获取values 后面的值参数字符串
	    	String valueSql = sql.substring(sql.toLowerCase().indexOf("values")+6);
	    	if(params != null && params.length > 0){
	    		Object[] insParams = new Object[params.length*params[0].length];
		    	for(int i = 0 ,j = 0; i<params.length ;i++){
		    		if(i != 0){
		    			sql = sql +","+valueSql;
		    		}
		    		for(Object obj : params[i]){
		    			insParams[j++] = obj;
		    		}
		    	}
	    		
		    	 try{
			            r =  mfr.update(DbManager.getConnection(),sql,insParams);
			        }catch(SQLException e){
			        	 e.printStackTrace();  
			        	  LOG.error("batchInsert.批量插入记录错误：" + sql, e); 
			        }finally{
			        	 DbManager.closeConnection();
			        }
	    	}
	        return r;
	        
	    }	    
	 
	 
	 
//   public static void main(String[] args){
//	   ResultSetHandler<List<XaCity>> h = new BeanListHandler<XaCity>(XaCity.class);
//		// TODO Auto-generated method stub
//		String insSql = "insert  into xa_city (xa_city_name,del_sts) values(?,1)";
//		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//			Object[][] ss = new Object[10][1];
//			for(int i =0 ;i < 10;i++){
//				ss[i][0] = "yssss"+i;
//			}
//			System.out.println(batchInsert(insSql,ss));
//   }
}
